package com.carbon.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.carbon.common.core.domain.AjaxResult;
import com.carbon.common.core.domain.entity.SysUser;
import com.carbon.common.core.text.Convert;
import com.carbon.common.utils.poi.ExcelUtil;
import com.carbon.domain.*;
import com.carbon.dto.*;
import com.carbon.mapper.BatchMapper;
import com.carbon.mapper.WareMapper;
import com.carbon.service.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.carbon.utils.OrderIdUtil;
import com.carbon.utils.QiniuUtils;
import com.carbon.vo.SearchParams;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

/**
 * 商品信息(Goods)表控制层
 *
 * @author WangFK
 * @since 2023-08-24 13:51:18
 */
@RestController
@Slf4j
@RequestMapping("/wms/goods")
public class GoodsController {
    /**
     * 服务对象
     */
    @Resource
    private GoodsService goodsService;
    @Resource
    private QiniuUtils qiniuUtils;
    @Resource
    private StorageGoodsService storageGoodsService;
    @Resource
    private ProviderService providerService;
    @Resource
    private WareMapper wareMapper;
    @Resource
    private WareService wareService;
    @Resource
    private BatchMapper batchMapper;
    @Resource
    private BatchService batchService;

    /**
     * 根据分页条件导出
     * @param response
     * @param params
     */
    @PostMapping("/export")
    public void export(HttpServletResponse response, SearchParams params)
    {
        AjaxResult list1 = list(params);
        List<GoodDto> rows = JSONUtil.toList(JSONUtil.toJsonStr(list1.get("rows")), GoodDto.class);
        ExcelUtil<GoodDto> util = new ExcelUtil<GoodDto>(GoodDto.class);
        util.exportExcel(response, rows, "库存报表");
    }

    /**
     * 删除补货申请中间表
     *
     * @param storageId
     * @param goodsId
     * @return
     */
    @DeleteMapping("/delStorageInfoGoods")
    public AjaxResult delStorageInfoGoods(String storageId, String goodsId) {
        List<String> split = StrUtil.split(goodsId, ",");
        LambdaUpdateWrapper<StorageGoods> lqw = new LambdaUpdateWrapper<StorageGoods>()
                .eq(StorageGoods::getStorageId, storageId)
                .in(StorageGoods::getGoodsId, split);
        return storageGoodsService.remove(lqw) ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 所有商品 不能解决前端 级联菜单 不显示数据  goodsSelectDtos 没值
     *
     * @return
     */
    @GetMapping("/SelectGoodsList")
    public AjaxResult SelectGoodsList(String storageId) {
        LambdaUpdateWrapper<Goods> lqw = new LambdaUpdateWrapper<Goods>()
                .eq(Goods::getGoodsStatus, "0")
                .ge(Goods::getGoodsNum, "0");
//        if (ObjectUtil.isNotEmpty(storageId)){
//            LambdaUpdateWrapper<StorageGoods> lqw1 = new LambdaUpdateWrapper<>();
//            lqw1.eq(StorageGoods::getStorageId,storageId);
//            List<Integer> collect = storageGoodsService.list(lqw1).stream().map(StorageGoods::getGoodsId).distinct().collect(Collectors.toList());
//            lqw.notIn(Goods::getId,collect);
//        }
        List<Goods> list = goodsService.list(lqw);
        if (list.isEmpty()) {
            return AjaxResult.success();
        }
        ArrayList<GoodsSelectDto> goodsSelectDtos = new ArrayList<>();
        GoodsSelectDto goodsSelectDto = new GoodsSelectDto();
        // 原料所需信息
        goodsSelectDto.setGoodsName("原料");
        goodsSelectDto.setId(1);
        // 原料详细信息
        goodsSelectDto.setChildren(list.stream().filter(item -> {
            if (!"1".equalsIgnoreCase(item.getGoodsType())) {
                return false;
            }
            return true;
        }).distinct().collect(Collectors.toList()));
        // 物料所需信息
        GoodsSelectDto goodsSelectDto1 = new GoodsSelectDto();
        goodsSelectDto1.setGoodsName("物料");
        goodsSelectDto1.setId(0);
        goodsSelectDto1.setChildren(list.stream().filter(item -> {
            if (!"0".equalsIgnoreCase(item.getGoodsType())) {
                return false;
            }
            return true;
        }).distinct().collect(Collectors.toList()));
        goodsSelectDtos.add(goodsSelectDto1);
        goodsSelectDtos.add(goodsSelectDto);
        return AjaxResult.success(goodsSelectDtos);
    }

    /**
     * 修改商品状态
     *
     * @param id
     * @param goodsStatus
     * @return
     */
    @GetMapping("/changeGoodsStatus")
    public AjaxResult changeGoodsStatus(String id, String goodsStatus) {
        Goods goods = new Goods();
        goods.setId(Convert.toInt(id));
        goods.setGoodsStatus(goodsStatus);
        return goodsService.updateById(goods) ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 分页
     *
     * @param params
     * @return
     */
    @GetMapping("/list")
    public AjaxResult list(SearchParams params) {
        String search = params.getSearch();
        // 仓库
        List<String> wareList = params.getWareList();
        // 生产单位 生产批号
        List<String> productNameList = params.getProductNameList();
        String goodsType = params.getGoodsType();
        Page<Goods> goodsPage = new Page<>(params.getPageNum(), params.getPageSize());
        LambdaUpdateWrapper<Goods> lqw = new LambdaUpdateWrapper<Goods>()
                .eq(ObjectUtil.isNotEmpty(goodsType), Goods::getGoodsType, goodsType)
                .eq(ObjectUtil.isNotEmpty(params.getRecordType()), Goods::getRecordType, params.getRecordType())
                .eq(ObjectUtil.isNotEmpty(params.getRecordSize()), Goods::getRecordSize, params.getRecordSize())
                .eq(ObjectUtil.isNotEmpty(params.getProviderId()), Goods::getProviderId, params.getProviderId())
                .orderByAsc(Goods::getSort)
                .orderByAsc(Goods::getCreateTime);
        if (ObjectUtil.isNotEmpty(search)) {
            lqw.like(Goods::getRecordId, search).or()
                    .like(Goods::getRecordName, search).or()
                    .like(Goods::getRecordPrice, search).or()
                    .like(Goods::getGoodsName, search);
        }
        if (params.getParentId() == null || !params.getParentId().toString().equalsIgnoreCase("0")) {
            lqw.ne(Goods::getParentId, "0");
        } else {
            lqw.eq(Goods::getParentId, "0");
        }
        if (ObjectUtil.isNotEmpty(wareList)){
            lqw.eq(Goods::getWareId,wareList.get(wareList.size()-1));
        }
        if (ObjectUtil.isNotEmpty(productNameList)){
            lqw.eq(Goods::getBatchId,productNameList.get(productNameList.size()-1));
        }

        goodsPage = goodsService.page(goodsPage, lqw);
        List<Goods> records = goodsPage.getRecords();
        if (ObjectUtil.isEmpty(records)) {
            return AjaxResult.success();
        }
        List<GoodDto> recordDtos = BeanUtil.copyToList(records, GoodDto.class);
        recordDtos.stream().forEach(item -> {
            Batch batch = batchService.getProductByBatchId(item.getBatchId());
            if (ObjectUtil.isNotEmpty(batch)) {
                item.setProductInfoName(batch.getProductName());
                item.setBatchName(batch.getBatchId());
            }
            WareDto wareDto = wareService.getWareNodeById(item.getWareId());
            if (ObjectUtil.isNotEmpty(wareDto)) {
                item.setWarePositionDto(wareDto.getWarePositionDto());
                item.setWareNameDto(wareDto.getWareNameDto());
                item.setWareAreaDto(wareDto.getWareAreaDto());
            }
            if (!item.getParentId().toString().equalsIgnoreCase("0")) {
                Provider byId = providerService.getById(item.getProviderId());
                if (byId != null) {
                    item.setProviderName(byId.getName());
                }
            }
        });
        return AjaxResult.success()
                .put("rows", recordDtos)
                .put("total", goodsPage.getTotal());
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("{id}")
    public AjaxResult selectOne(@PathVariable Serializable id) {
        Goods byId = goodsService.getById(id);
        GoodDto goodDto = new GoodDto();
        BeanUtil.copyProperties(byId,goodDto);
        // 仓库
        WareDto wareIdNodeById = wareMapper.getWareIdNodeById(goodDto.getWareId());
        // 批号
        BatchDto productIdByBatchId = batchMapper.getProductIdByBatchId(goodDto.getBatchId());
        if (ObjectUtil.isNotEmpty(wareIdNodeById)){
            goodDto.setWareName(ListUtil.toList(Convert.toLong(wareIdNodeById.getWareNameDtoId()), Convert.toLong(wareIdNodeById.getWareAreaDtoId()), Convert.toLong(wareIdNodeById.getWarePositionDtoId())));

        }
        if (ObjectUtil.isNotEmpty(productIdByBatchId)){
            goodDto.setProductName(ListUtil.toLinkedList(Convert.toLong(productIdByBatchId.getProductId()),Convert.toLong(productIdByBatchId.getBatchId())));

        }
        return AjaxResult.success(goodDto);
    }

    /**
     * 查询所有父类
     *
     * @return
     */
    @GetMapping("/getRecordInfoList")
    public AjaxResult getRecordInfoList() {
        LambdaUpdateWrapper<Goods> lqw = new LambdaUpdateWrapper<Goods>()
                .eq(Goods::getParentId, "0")
                .eq(Goods::getGoodsStatus, "0")
                .orderByAsc(Goods::getSort)
                .orderByAsc(Goods::getCreateTime);
        List<Goods> list = goodsService.list(lqw);
        if (ObjectUtil.isEmpty(list)) {
            return AjaxResult.success();
        }
        return AjaxResult.success(list);
    }

    /**
     * 新增数据
     *
     * @param goods 实体对象
     * @return 新增结果
     */
    @PostMapping
    public AjaxResult insert(@RequestBody GoodDto goods) {
        String recordId = goods.getRecordId();
        if (recordId != null) {
            recordId = OrderIdUtil.getOrderId(recordId);
        } else {
            recordId = OrderIdUtil.getOrderId();
        }
        goods.setRecordId(recordId);
        // 子项 合法性判断
        if (!goods.getFlag().equalsIgnoreCase("0")) {
            AjaxResult result = Illegality(goods);
            if (result != null) {
                return result;
            }
        }
        if (!"0".equalsIgnoreCase(goods.getFlag())) {
            Goods byId = goodsService.getById(goods.getParentId());
            if (byId != null) {
                goods.setRecordName(byId.getGoodsName());
            }
        }

        goods.setGoodsPrice(goods.getRecordPrice());
        if (ObjectUtil.isNotEmpty(goods.getId())) {
            return update(goods);
        }
        if (ObjectUtil.isNotEmpty(goods.getGoodsTotal())) {
            goods.setGoodsNum(goods.getGoodsTotal());
        }
        LambdaUpdateWrapper<Goods> lqw = new LambdaUpdateWrapper<Goods>()
                .eq(Goods::getGoodsName, goods.getGoodsName());
        List<Goods> list = goodsService.list(lqw);
        if (ObjectUtil.isNotEmpty(list)) {
            return AjaxResult.error("商品名：" + goods.getGoodsName() + "重复");
        }
        return goodsService.save(goods) ? AjaxResult.success() : AjaxResult.error();
    }

    private static AjaxResult Illegality(GoodDto goods) {
        if (ObjectUtil.isEmpty(goods.getGoodsName())) {
            return AjaxResult.error("商品名为空");
        }
        if (ObjectUtil.isEmpty(goods.getGoodsImg())) {
            return AjaxResult.error("商品图片为空");
        }
        if (goods.getProviderId() == null) {
            return AjaxResult.error("供应商为空");
        }
        if (goods.getParentId() == null) {
            return AjaxResult.error("所属分类为空");
        }
        if (goods.getRecordType() == null) {
            return AjaxResult.error("选择类型为空");
        }
        if (ObjectUtil.isEmpty(goods.getWareName())){
            return AjaxResult.error("仓库为空");
        }
        if (ObjectUtil.isEmpty(goods.getProductName())){
            return AjaxResult.error("生产单位为空");
        }
        return null;
    }

    /**
     * 修改数据
     *
     * @param goods 实体对象
     * @return 修改结果
     */
    @PutMapping
    public AjaxResult update(@RequestBody GoodDto goods) {
        String type = goods.getType();
        if ("2".equalsIgnoreCase(type)){
            List<Long> wareName = goods.getWareName();
            Goods goods1 = new Goods();
            goods1.setId(goods.getId());
            goods1.setWareId(Convert.toInt(wareName.get(wareName.size()-1)));
            return goodsService.updateById(goods1)?AjaxResult.success():AjaxResult.error();
        }
        Goods byId = goodsService.getById(goods.getId());
        String goodsImg = byId.getGoodsImg();
        String goodsName = byId.getGoodsName();
        if (!goods.getGoodsName().equalsIgnoreCase(goodsName)) {
            LambdaUpdateWrapper<Goods> lqw = new LambdaUpdateWrapper<Goods>()
                    .eq(Goods::getGoodsName, goods.getGoodsName());
            List<Goods> list = goodsService.list(lqw);
            if (ObjectUtil.isNotEmpty(list)) {
                return AjaxResult.error("商品名：" + goods.getGoodsName() + "重复");
            }
        }
        if (!goods.getGoodsImg().equalsIgnoreCase(goodsImg)) {
            List<String> split = StrUtil.split(goodsImg, "/");
            qiniuUtils.deleteFileFromQiniu(split.get(split.size() - 1));
        }
        return goodsService.updateById(goods) ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 删除数据
     *
     * @param id 主键结合
     * @return 删除结果
     */
    @DeleteMapping("{id}")
    public AjaxResult delete(@PathVariable String id) {
        List<String> split = StrUtil.split(id, ",");
        goodsService.listByIds(split).stream().filter(item -> {
            if (ObjectUtil.isEmpty(item.getGoodsImg())) {
                return false;
            }
            return true;
        }).map(Goods::getGoodsImg).distinct().forEach(img -> {
            List<String> split1 = StrUtil.split(img, "/");
            qiniuUtils.deleteFileFromQiniu(split1.get(split1.size() - 1));
        });
        LambdaUpdateWrapper<Goods> lqw = new LambdaUpdateWrapper<Goods>()
                .in(Goods::getId, split);
        return goodsService.remove(lqw) ? AjaxResult.success() : AjaxResult.error();
    }
}

